
var defaultOpts = {
    style: 'plain',  //plain简约风格，normal常规风格，card卡片风格
    actItemBackColor: '#ffffff',
    actItemFontColor: '#005FFF',
    headerBackColor: undefined,
    autoScroll: true,//自动隐藏滚动条
    ifrScroll:true,
    reload: false,//点击刷新加载
    ctxmenu: true,
    openTab: false, //是否显示在浏览器新页打开
    position: "top",
    headSize: '35px',
    moreBtnSize: 14,
    tabs: undefined,
    bodyItemStyle:undefined,
    bodyStyle:undefined,
    moreBtnCss: { background: "#fff", "border-bottom": "1px solid rgb(218, 220, 224)" }
};

class Tabs extends $B.BaseControl {
    constructor(elObj, opts) {
        super();
        super.setElObj(elObj);
        $B.DomUtils.addClass(this.elObj, "k_tab_wrap k_box_size");
        $B.DomUtils.css(this.elObj, { "overflow": "hidden" });
        this.opts = $B.extendObjectFn(true, {}, defaultOpts, opts);
        this.morePaddLeft = 0;
        this.readerUI();
        var checker;
        $B.DomUtils.resize(window, (e) => {
            clearTimeout(checker);
            checker = setTimeout(() => {
                this.checkOverFlow();
            }, 300);
        });
    }
    /**
     * 根据Id激活某一个选项卡
     * **/
    activedById(id){
        let els = this.tabHeader.firstChild.children;
        for (let i = 0; i < els.length; i++) {
            if ($B.DomUtils.attribute(els[i], "id") === id) {
                this.onClickEv(els[i], () => {
                    setTimeout(() => {
                        this.movebyAct();
                    }, 1);
                });
                return true;
            }
        }
        return false;
    }
     /**
     * args = {
            fixed:true,
            id:'0001',
            text: "用户管理",
            iconCls: 'fa-user',
            content: '<p style="color:red">用户管理</p>'
        }
     * ***/
    add(args) {
        let id = args.id;
        if(this.activedById(id)){
            return;
        }
        if (this.opts.position === "top" || this.opts.position === "bottom") {
            let idx = 0;
            let nextIdx = 0;
            let $actIt = this.$activeted;
            if ($actIt) {
                idx = parseInt($B.DomUtils.attribute($actIt, "index"));
                nextIdx = idx + 1;
                let newTabs = [];
                for (let i = 0; i < this.opts.tabs.length; i++) {
                    newTabs.push(this.opts.tabs[i]);
                    if (i === idx) {
                        newTabs.push(args);
                    }
                }
                this.opts.tabs = newTabs;
            } else {
                this.opts.tabs = [args];
            }           
            let $it = this._createHorizItem(args, nextIdx, ($t, $b) => {
                let childs = this.tabHeader.firstChild.children;
                if (childs.length > 0) {
                    let el = childs[idx];
                    $B.DomUtils.after(el, $t);
                    childs = this.tabBody.children;
                    el = childs[idx];
                    $B.DomUtils.after(el, $b);
                    let nextEl = $t.nextSibling;
                    while(nextEl){
                        let newIdx = parseInt($B.DomUtils.attribute(nextEl, "index")) + 1;
                        $B.DomUtils.attribute(nextEl, {"index":newIdx});
                        nextEl = nextEl.nextSibling;
                    }
                } else {
                    $B.DomUtils.append(this.tabHeader.firstChild, $t);
                    $B.DomUtils.append(this.tabBody, $b);
                }
                setTimeout(() => {
                    this.checkOverFlow();
                }, 100);
            });           
            this.onClickEv($it, () => {
                setTimeout(() => {
                    this.movebyAct();
                }, 1);
            });
        }
    }
    movebyAct() {
        let $wap = this.$activeted.parentNode;
        let $prt = $wap.parentNode;
        let innerWidth = $B.DomUtils.width($wap);
        let prtWidth = $B.DomUtils.innerWidth($prt);
        let left = Math.abs($B.DomUtils.css($wap, "left"));
        let itWidth = $B.DomUtils.outerWidth(this.$activeted);
        let pos = 0;
        let $el = this.$activeted;
        while ($el) {
            pos = pos + $B.DomUtils.outerWidth($el);
            $el = $el.previousSibling;
        }
        let diff = pos - left;
        if (diff > prtWidth) {
            let shift = prtWidth - diff - left;
            $B.animate($wap, { left: shift }, {
                duration: 100, complete: () => {
                    if (this.$actLine) {
                        this._updateHActLinePos();
                    }
                }
            });
        } else if (diff < itWidth) {
            let shift = - (pos - itWidth);
            if (shift > 0) {
                shift = 0;
            }
            $B.animate($wap, { left: shift }, {
                duration: 100, complete: () => {
                    if (this.$actLine) {
                        this._updateHActLinePos();
                    }
                }
            });
        }
        if (this.$rbtn) {
            if (innerWidth > prtWidth) {
                if (this.$activeted.nextSibling) {
                    $B.DomUtils.removeClass(this.$rbtn, "k_tabs_more_disabled");
                    $B.DomUtils.addClass(this.$rbtn.firstChild, "enabled");
                } else {
                    $B.DomUtils.addClass(this.$rbtn, "k_tabs_more_disabled");
                    $B.DomUtils.removeClass(this.$rbtn.firstChild, "enabled");
                }
                if (this.$activeted.previousSibling) {
                    $B.DomUtils.removeClass(this.$lbtn, "k_tabs_more_disabled");
                    $B.DomUtils.addClass(this.$lbtn.firstChild, "enabled");
                } else {
                    $B.DomUtils.addClass(this.$lbtn, "k_tabs_more_disabled");
                    $B.DomUtils.removeClass(this.$lbtn.firstChild, "enabled");
                }
            } else {
                setTimeout(() => {
                    this.checkOverFlow();
                    this._updateHActLinePos()
                }, 100);
            }
        }
    }
    delete(idOrTxt) {
        if (this.opts.position === "top" || this.opts.position === "bottom") {
            let childs = this.tabHeader.firstChild.children;
            let deleteEl;
            for (let i = 0; i < childs.length; i++) {
                let el = childs[i];
                let id = $B.DomUtils.attribute(el, "id");
                let txt = el.innerText;
                if (id === idOrTxt || txt === idOrTxt) {
                    deleteEl = el;
                    break;
                }
            }
            if (deleteEl) {
                this._removeOneIt(deleteEl);
            }
        }
    }
    readerVertical() {
        var tabs = this.opts.tabs;
        var thtml = "<div style='width:100%;' class='clearfix k_tab_item_v_" + this.opts.position + " k_tab_item k_box_size'><span style='line-height:1.3em'></span></div>";
        var bhtml = "<div class='k_tab_item_body k_box_size' style='display:none;position:relative;'></div>";
        var activedIt;
        var $wrap = this.tabHeader.firstChild;
        $B.DomUtils.css(this.tabHeader, { height: '100%' });
        var srolOpt = {};
        var _this = this;
        if (this.opts.position === "right") {
            srolOpt.onScrollFn = function (scrollx, scrolly) {
                let top = parseFloat($B.DomUtils.attribute(_this.$actLine, "top")) - scrolly;
                $B.DomUtils.css(_this.$actLine, { top: top });
            };
        }
        $wrap = $B.myScrollbar($wrap, srolOpt);
        this.$iArray = [];
        for (let i = 0; i < tabs.length; i++) {
            let tab = tabs[i];
            let $t = $B.DomUtils.createEl(thtml);
            let attr = { index: i };
            if (tab.id) {
                attr["id"] = tab.id;
            }
            $B.DomUtils.attribute($t, attr);
            if (tab.text) {
                $t.firstChild.innerHTML = tab.text;
            }
            if (tab.iconCls) {
                if (this.opts.position === "left") {
                    $B.DomUtils.prepend($t, "<i style='float:left;padding-right:8px;font-size:1.2em;' class='fa " + tab.iconCls + "'></i>");
                    this.$iArray.push($t.firstChild);
                } else {
                    $B.DomUtils.css($t.firstChild, { "display": "block", "float": "left" });
                    $B.DomUtils.append($t, "<i style='float:right;padding-right:2px;font-size:1.2em;' class='fa " + tab.iconCls + "'></i>");
                    this.$iArray.push($t.lastChild);
                }
            }
            let $b = $B.DomUtils.createEl(bhtml);
            if(this.opts.bodyItemStyle){
                $B.Dom.css($b,this.opts.bodyItemStyle);
            }
            if (tab.content) {
                if ($B.DomUtils.isElement(tab.content)) {
                    if (tab.content.parentNode) {
                        $B.DomUtils.detach(tab.content);
                    }
                    $B.DomUtils.append($b, tab.content);
                } else {
                    $b.innerHTML = tab.content;
                }
            }
            let clzz = "k_tab_it_" + this.opts.position + "_" + this.opts.style;
            $B.DomUtils.addClass($t, clzz);
            $B.DomUtils.append($wrap, $t);
            if (this.opts.autoScroll && $B.myScrollbar && tab.dataType !== "iframe") {
                let $c = $B.myScrollbar($b, {});
                $B.DomUtils.addClass($b, "k_tab_diyscroll");
                $B.DomUtils.css($b, { height: "100%" });
                if(tab.height){
                    $B.Dom.css($c,{"height":tab.height});
                }
            }
            $B.DomUtils.append(this.tabBody, $b);
            if (i === 0 || tab.actived) {
                activedIt = $t;
            }
        }
        if (this.opts.style === "plain") {
            if (this.opts.position === "left") {
                $B.DomUtils.css(this.tabHeader.firstChild, { "border-right": "1px solid #DADCE0" });
                this.$actLine = $B.DomUtils.createEl("<div class='k_tabs_act_line' style='display:inline-block;position:absolute;right:0px;width:2px;top:-300px;height:50px;'></div>");
            } else {
                $B.DomUtils.css(this.tabHeader.firstChild, { "border-left": "1px solid #DADCE0" });
                this.$actLine = $B.DomUtils.createEl("<div class='k_tabs_act_line' style='display:inline-block;position:absolute;left:0px;width:2px;top:-300px;height:50px;'></div>");
            }
            $B.DomUtils.append(this.tabHeader, this.$actLine);
        } else {
            $B.DomUtils.css(this.tabHeader, { "background-color": this.opts.headerBackColor });
        }
        this.$activeted = activedIt;
    }
    _resetHeaderIndex($activeted) {
        if ($activeted) {
            this._resetIndex($activeted);
            this.checkOverFlow();
            this._updateHActLinePos();
        }
    }
    _resetIndex($activeted){   
        console.log("_resetIndex",$activeted);     
        let childNodes = $activeted.parentNode.children;
        for (let i = 0; i < childNodes.length; i++) {
            let $i = childNodes[i];
            $B.DomUtils.attribute($i, { "index": i });
        }
    }
    _removeOneIt($it) {
        let $actIt;
        if (this.$activeted && this.$activeted === $it) {
            if ($it.previousSibling) {
                $actIt = $it.previousSibling;
            } else if ($it.nextSibling) {
                $actIt = $it.nextSibling;
            } else {
                this.$activeted = undefined;
            }
            this.$actbody = undefined;
        }
        this._exeRmItem($it);
        if ($actIt) {
            this.$activeted = $actIt;
        }
        this._resetHeaderIndex(this.$activeted);
        if ($actIt) {
            this.$activeted = undefined;
            setTimeout(() => {
                this.onClickEv($actIt);
            }, 1);
        }
    }
    _exeRmItem($it){
        let idx = parseInt($B.DomUtils.attribute($it, "index"));
        let childs = this.tabBody.children;
        let actBody = childs[idx];
        $B.DomUtils.remove(actBody);
        $B.DomUtils.remove($it);
        var newOpts = [];
        for (let i = 0; i < this.opts.tabs.length; i++) {
            if (i !== idx) {
                newOpts.push(this.opts.tabs[i]);
            }
        }
        this.opts.tabs = newOpts;
        if (newOpts.length === 0) {
            this.$actLine.style.display = "none";
        }
    }
    _bindCloseable($it) {
        if (!this.closeEvents) {
            this.closeEvents = {
                click: (e) => {
                    let el = e.target;
                    this._removeOneIt(el.parentNode);
                    if(this.opts.onClosed){
                       setTimeout(()=>{
                            this.opts.onClosed(el,this.$activeted);
                       },200);
                    }
                    return false;
                }
            };
            if (this.opts.haverClose) {
                this.closeEvents.mouseenter = (e) => {
                    let el = e.target;
                    el.lastChild.style.display = "block";
                };
                this.closeEvents.mouseleave = (e) => {
                    let el = e.target;
                    el.lastChild.style.display = "none";
                };
            }
        }
        var $close = $B.DomUtils.createEl('<i style="position:absolute;top:-1px;right:-2px;font-size:13px;cursor:pointer;" class="fa fa-cancel-1"></i>');
        if (this.opts.haverClose) {
            $close.style.display = "none";
            $B.DomUtils.mouseenter($it, this.closeEvents.mouseenter);
            $B.DomUtils.mouseleave($it, this.closeEvents.mouseleave);
        }
        $B.DomUtils.append($it, $close);
        $B.DomUtils.click($close, this.closeEvents.click);
    }
    _createHorizItem(tab, i, onCreatedFn) {
        var lineHeight = parseInt(this.opts.headSize.replace("px", "")) - 1;
        var thtml = "<div class='k_tab_item_h k_tab_item k_box_size'><span style='line-height:" + lineHeight + "px;'></span></div>";
        var bhtml = "<div class='k_tab_item_body k_box_size' style='display:none;background-color:#fff;position:relative;'></div>";
        let $b = $B.DomUtils.createEl(bhtml);
        let $t = $B.DomUtils.createEl(thtml);
        if(this.opts.bodyItemStyle){
            $B.Dom.css($b,this.opts.bodyItemStyle);
        }        
        let attr = { index: i };
        if (tab.id) {
            attr["id"] = tab.id;
        }
        $B.DomUtils.attribute($t, attr);
        $B.DomUtils.attribute($b, attr);
        if (tab.text) {
            $t.firstChild.innerHTML = tab.text;
        }
        if (tab.iconCls) {
            $B.DomUtils.prepend($t, "<i style='line-height:" + lineHeight + "px' class='fa " + tab.iconCls + "'></i>");
        }       
        if (tab.content) {
            if ($B.DomUtils.isElement(tab.content)) {
                if (tab.content.parentNode) {
                    $B.DomUtils.detach(tab.content);
                }
                $B.DomUtils.append($b, tab.content);
            } else {
                $b.innerHTML = tab.content;
            }
        }
        if (this.opts.autoScroll && $B.myScrollbar && tab.dataType !== "iframe") {
            let $c = $B.myScrollbar($b, {});
            $B.DomUtils.addClass($b, "k_tab_diyscroll");
            $B.DomUtils.css($b, { height: "100%" });
            if(tab.height){
                $B.Dom.css($c,{"height":tab.height});
            }
        }
        let clzz = "k_tab_it_" + this.opts.position + "_" + this.opts.style;
        $B.DomUtils.addClass($t, clzz);
        onCreatedFn($t, $b);
        if (this.opts.style === "normal") {
            if (i !== 0) {
                $B.DomUtils.css($t, { "border-left": "none" });
            }
        }
        if (this.opts.headerBackColor) {
            $B.DomUtils.css($t, { "border-top": "none" });
        }
        if (this.opts.closeable && !tab.fixed) {
            this._bindCloseable($t);
        }
        return $t;
    }
    /**
     * 水平tab ui
     * ***/
    readerHoriz() {
        var tabs = this.opts.tabs;
        var activedIt;
        for (let i = 0; i < tabs.length; i++) {
            let tab = tabs[i];
            let $t = this._createHorizItem(tab, i, ($t, $b) => {
                $B.DomUtils.append(this.tabHeader.firstChild, $t);
                $B.DomUtils.append(this.tabBody, $b);
            });
            if (i === 0 || tab.actived) {
                activedIt = $t;
            }
        }
        if (this.opts.style === "plain") {
            //采用下划线模式
            $B.DomUtils.css(this.tabHeader.firstChild, { "border-bottom": "1px solid #DADCE0" });
            this.$actLine = $B.DomUtils.createEl("<div class='k_tabs_act_line' style='display:inline-block;position:absolute;bottom:0px;height:2px;left:-100px;width:50px;'></div>");
            $B.DomUtils.append(this.tabHeader, this.$actLine);           
        } else { //normal
            let actLinePos = "bottom";
            if (this.opts.position === "bottom") {
                actLinePos = "top";
            }
            $B.DomUtils.css(this.tabHeader.firstChild, { "border-bottom": "1px solid #DADCE0" });
            this.$actLine = $B.DomUtils.createEl("<div class='k_tabs_act_line' style='display:inline-block;position:absolute;" + actLinePos + ":0px;height:2px;left:-300px;width:50px;background-color:" + this.opts.actItemBackColor + "'></div>");
            $B.DomUtils.append(this.tabHeader, this.$actLine);
            this.opts.moreBtnCss["border-top"] = "1px solid #DADCE0";
            this.opts.moreBtnCss["border-right"] = "1px solid #DADCE0";
            this.opts.moreBtnCss["border-left"] = "1px solid #DADCE0";
        }
        this.$activeted = activedIt;
        if (this.opts.headerBackColor) {
            $B.DomUtils.css(this.tabHeader.firstChild, { "border-right": "1px solid #DADCE0" });
            $B.DomUtils.css(this.tabHeader.firstChild, { "border-top": "1px solid #DADCE0" });
            $B.DomUtils.css(this.tabHeader, { "background-color": this.opts.headerBackColor });
        }
        if(this.opts.headerStyle){
            $B.DomUtils.css(this.tabHeader.firstChild, this.opts.headerStyle);
        }
        //右键菜单功能
        $B.DomUtils.contextmenu(document, (e) => {
            let el = e.target;
            if ($B.DomUtils.hasClass(el, "k_tab_item") || $B.DomUtils.hasClass(el.parentNode, "k_tab_item")) {
                return false;
            }
        });
    }
    readerUI() {
        var position = this.opts.position;
        this.tabHeader = $B.DomUtils.createEl("<div class='k_tab_header k_box_size'><div class='k_box_size k_tabs_head_it_wrap' style='min-width:100%;height:100%;position:relative;'></div></div>");
        this.tabBody = $B.DomUtils.createEl("<div class='k_tab_body k_box_size'></div>"); 
        if(this.opts.bodyStyle){
            $B.Dom.css($b,this.opts.bodyStyle);
        }       
        var headerCss, bodyCss;
        if (position === "top") {
            headerCss = { top: 0, left: 0, width: '100%', height: this.opts.headSize, "white-space": 'nowrap', "overflow": "hidden" };
            bodyCss = { "border-top": this.opts.headSize + " solid #ffffff" };
            $B.DomUtils.css(this.tabHeader.firstChild, { "white-space": 'nowrap' });
            this.readerHoriz();
        } else if (position === "bottom") {
            headerCss = { bottom: 0, left: 0, width: '100%', height: this.opts.headSize, "white-space": 'nowrap', "overflow": "hidden" };
            bodyCss = { "border-bottom": this.opts.headSize + " solid #ffffff" };
            $B.DomUtils.css(this.tabHeader.firstChild, { "white-space": 'nowrap' });
            this.readerHoriz();
        } else if (position === "left") {
            headerCss = { top: 0, left: 0, height: '100%', width: this.opts.headSize };
            bodyCss = { "border-left": this.opts.headSize + " solid #ffffff" };
            this.readerVertical();
        } else if (position === "right") {
            headerCss = { top: 0, right: 0, width: '100%', width: this.opts.headSize };
            bodyCss = { "border-right": this.opts.headSize + " solid #ffffff" };
            this.readerVertical();
        }
        $B.DomUtils.css(this.tabHeader, headerCss);
        $B.DomUtils.css(this.tabBody, bodyCss);
        $B.DomUtils.append(this.elObj, this.tabBody);
        $B.DomUtils.append(this.elObj, this.tabHeader);
        if(this.opts.headerStyle){
            $B.DomUtils.css(this.tabHeader.firstChild, this.opts.headerStyle);
        }
        if (this.opts.ctxmenu && (position === "top" || position === "bottom")) {
            $B.DomUtils.mouseup(this.tabHeader, (e) => {
                if (e.which === 3) {
                    let el = e.target;
                    if ($B.DomUtils.hasClass(el, "k_tab_header")) {
                        return true;
                    }
                    while (el) {
                        if ($B.DomUtils.hasClass(el, "k_tab_item")) {
                            break;
                        }
                        el = el.parentNode;
                    }
                    if (!this.$ctxmenu) {
                        this.createCtxMenu();
                        $B.DomUtils.append(document.body, this.$ctxmenu);
                    }
                    this.$oprIt = el;
                    var ofs = $B.DomUtils.offset(el);
                    var h = $B.DomUtils.outerHeight(el);
                    var w = $B.DomUtils.outerWidth(el);
                    ofs.top = ofs.top + h;
                    this.$ctxmenu.style.top = ofs.top + "px";
                    this.$ctxmenu.style.left = ofs.left + "px";
                    if (w > 115) {
                        this.$ctxmenu.style.width = w + "px";
                    } else {
                        this.$ctxmenu.style.width = "115px";
                    }
                    $B.slideDown(this.$ctxmenu, 100);
                }
            });
        }
        $B.DomUtils.click(this.tabHeader, (e) => {
            let el = e.target;
            if ($B.DomUtils.hasClass(el, "k_tab_header")) {
                return true;
            }
            while (el) {
                if ($B.DomUtils.hasClass(el, "k_tab_item")) {
                    break;
                }
                el = el.parentNode;
            }
            this.onClickEv(el);
            if (this.opts.onClick) {
                let id = $B.DomUtils.attribute(el, "id");
                let text = $B.DomUtils.children(el, "span")[0].innerText;
                this.opts.onClick.call(el, id, text);
            }
        });
        var $it = this.$activeted;
        this.$activeted = undefined;
        if (this.$iArray) {
            for (let i = 0; i < this.$iArray.length; i++) {
                let h, $i = this.$iArray[i];
                let $span = $B.DomUtils.children($i.parentNode, "span")[0];
                if (position === "right") {
                    let p_width = $B.DomUtils.innerWidth($i.parentNode);
                    let maxWidth = p_width - 25;
                    $B.DomUtils.width($span, maxWidth);
                    continue;
                }
                h = $B.DomUtils.height($span);
                if (h < 22) {
                    h = 22;
                }
                this.$iArray[i].style.lineHeight = h + "px";
            }
        }
        setTimeout(() => {
            this.checkOverFlow();
            this.onClickEv($it);
        }, 100);
    }
    createCtxMenu() {
        let cfg = $B.config.tabmenu;
        this.$ctxmenu = $B.DomUtils.createEl("<div style='position:absolute;display:none;width:115px;text-align:center;' class='k_dropdown_list_wrap k_tab_ctxmenu_wrap k_box_size'></div>");
        let $flash = $B.DomUtils.createEl("<div f='x_road' class='k_dropdown_list_item k_tab_ctxmenu'><i class='fa " + cfg.reload.icon + "'></i><span>" + cfg.reload.text + "</span></div>");
        let $closeNow = $B.DomUtils.createEl("<div f='x_closen' class='k_dropdown_list_item k_tab_ctxmenu'><i class='fa " + cfg.closeNow.icon + "'></i><span>" + cfg.closeNow.text + "</span></div>");
        let $closeRight = $B.DomUtils.createEl("<div f='x_closer' class='k_dropdown_list_item k_tab_ctxmenu'><i class='fa " + cfg.closeRight.icon + "'></i><span>" + cfg.closeRight.text + "</span></div>");
        let $closeLeft = $B.DomUtils.createEl("<div f='x_closel' class='k_dropdown_list_item k_tab_ctxmenu'><i class='fa " + cfg.closeLeft.icon + "'></i><span>" + cfg.closeLeft.text + "</span></div>");
        let $closeMenu = $B.DomUtils.createEl("<div f='x_closem' class='k_dropdown_list_item k_tab_ctxmenu'><i class='fa " + cfg.closeMenu.icon + "'></i><span>" + cfg.closeMenu.text + "</span></div>");
        let $openTab;
        if(this.opts.openTab){
            $openTab = $B.DomUtils.createEl("<div f='x_open' class='k_dropdown_list_item k_tab_ctxmenu'><i class='fa " + cfg.opened.icon + "'></i><span>" + cfg.opened.text + "</span></div>");
            $B.DomUtils.append(this.$ctxmenu, $openTab);
        }       
        $B.DomUtils.append(this.$ctxmenu, $flash);
        $B.DomUtils.append(this.$ctxmenu, $closeNow);
        $B.DomUtils.append(this.$ctxmenu, $closeRight);
        $B.DomUtils.append(this.$ctxmenu, $closeLeft);
        $B.DomUtils.append(this.$ctxmenu, $closeMenu);
        $B.DomUtils.click(this.$ctxmenu, (e) => {
            let el = e.target;
            if ($B.DomUtils.hasClass(el, "k_dropdown_list_wrap")) {
                return true;
            }
            while (el) {
                if ($B.DomUtils.hasClass(el, "k_dropdown_list_item")) {
                    break;
                }
                el = el.parentNode;
            }
            let f = $B.DomUtils.attribute(el, "f");
            if (f === "x_open") {
                this.openTabEv(this.$oprIt);
            }else if (f === "x_road") {
                this.onClickEv(this.$oprIt, true);
            } else if (f === "x_closen") {
                let $c = $B.DomUtils.children(this.$oprIt, ".fa-cancel-1");
                if ($c.length > 0) {
                    $B.DomUtils.trigger($c[0], "click");
                    this.checkOverFlow();
                }
            } else if (f === "x_closer") {
                let $opr = this.$oprIt;
                this.onClickEv($opr, () => {
                    let nextEl = $opr.nextSibling;
                    while (nextEl) {                     
                        let $c = $B.DomUtils.children(nextEl, ".fa-cancel-1");
                        let nEl = nextEl.nextSibling;
                        if ($c.length > 0) {                            
                            this._exeRmItem(nextEl);
                        }    
                        nextEl = nEl;                   
                    }
                    this.checkOverFlow();                    
                });
            } else if (f === "x_closel") {
                let $opr = this.$oprIt;
                this.onClickEv($opr, () => {
                    let preEl = $opr.previousSibling;
                    while (preEl) {
                        let $c = $B.DomUtils.children(preEl, ".fa-cancel-1");
                        let _preEl = preEl.previousSibling;
                        if ($c.length > 0) {
                            this._exeRmItem(preEl);
                            this._resetIndex(this.$activeted);
                        }   
                        preEl = _preEl;                    
                    }
                    this.checkOverFlow();
                    this._updateHActLinePos();
                });
            }
            $B.slideUp(this.$ctxmenu, 100, () => {
                this.$oprIt = undefined;
            });
        });
        $B.createGlobalBodyHideEv();
    }
    _bindMoreBtnEvent() {
        if (!this.rlevents) {
            this.rlevents = (e) => {
                let btn = e.target;
                if (btn.tagName === "I") {
                    btn = btn.parentNode;
                }
                if ($B.DomUtils.hasClass(btn, "k_tabs_more_disabled")) {
                    return false;
                }
                let childrens = this.tabHeader.firstChild.children;
                let isleft = $B.DomUtils.hasClass(btn, "_more_btn_l_");
                let moveLeft = 0;
                let nowLeft = $B.DomUtils.position(this.tabHeader.firstChild).left;
                let actEl, left, w, shiftLeft;
                if (isleft) {
                    let shiftLeft = Math.abs(nowLeft);
                    let shiftVal = 0;
                    for (let i = 0; i < childrens.length; i++) {
                        left = $B.DomUtils.position(childrens[i]).left;
                        w = $B.DomUtils.outerWidth(childrens[i]);
                        if (left > shiftLeft || (left + w) > shiftLeft) {
                            actEl = childrens[i];
                            if (actEl.previousSibling) {
                                actEl = actEl.previousSibling;
                                shiftVal = shiftVal - $B.DomUtils.outerWidth(actEl);
                            }
                            break;
                        } else {
                            shiftVal = shiftVal + w;
                        }
                    }
                    if (shiftVal > 0) {
                        moveLeft = -shiftVal;
                    }
                    $B.DomUtils.removeClass(this.$rbtn, "k_tabs_more_disabled");
                    $B.DomUtils.addClass(this.$rbtn.firstChild, "enabled");
                } else {
                    shiftLeft = nowLeft - this.opts.moreBtnSize;
                    let headWidth = $B.DomUtils.innerWidth(this.tabHeader);
                    for (let i = 0; i < childrens.length; i++) {
                        left = $B.DomUtils.position(childrens[i]).left + shiftLeft;
                        w = $B.DomUtils.outerWidth(childrens[i]);
                        if (Math.floor(left + w) > headWidth || left > headWidth) {
                            actEl = childrens[i];
                            break;
                        }
                    }
                    if (!actEl) {
                        return false;
                    }
                    if (!actEl.nextSibling) {//禁用右侧按钮
                        $B.DomUtils.addClass(this.$rbtn, "k_tabs_more_disabled");
                        $B.DomUtils.removeClass(this.$rbtn.firstChild, "enabled");
                    }
                    moveLeft = headWidth - left - w;
                    moveLeft = moveLeft + shiftLeft;
                }
                if (moveLeft > 0) {
                    moveLeft = 0;
                }
                $B.animate(this.tabHeader.firstChild, { left: moveLeft }, {
                    duration: 120, complete: () => {
                        if (this.$actLine) {
                            this._updateHActLinePos();
                        }
                    }
                });
                //修改左侧按钮状态
                if (moveLeft < 0) {
                    $B.DomUtils.removeClass(this.$lbtn, "k_tabs_more_disabled");
                    $B.DomUtils.addClass(this.$lbtn.firstChild, "enabled");
                } else {
                    $B.DomUtils.addClass(this.$lbtn, "k_tabs_more_disabled");
                    $B.DomUtils.removeClass(this.$lbtn.firstChild, "enabled");
                }
                return false;
            };
        }
        $B.DomUtils.click(this.$lbtn, this.rlevents);
        $B.DomUtils.click(this.$rbtn, this.rlevents);
    }
    checkOverFlow() {
        var position = this.opts.position;
        var $warp = this.tabHeader.firstChild;
        var childs = $warp.children;
        //水平位置
        if (position === "top" || position === "bottom") {
            var headWidth = Math.ceil($B.DomUtils.width(this.tabHeader));
            let allWidth = 0;
            for (let i = 0; i < childs.length; i++) {
                let w = Math.ceil($B.DomUtils.outerWidth(childs[i]));
                allWidth = allWidth + w;
            }
            if (allWidth > headWidth) {
                $B.DomUtils.css($warp, { width: allWidth });
                if (!this.$lbtn) {
                    let h = $B.DomUtils.height(this.tabHeader);
                    let $l = $B.DomUtils.createEl("<span style='left:0;' class='k_tabs_more_btn _more_btn_l_ k_tabs_more_disabled k_box_size'><i style='line-height:" + h + "px' class='fa fa-angle-double-left'></i></span>");
                    let $r = $B.DomUtils.createEl("<span style='right:0;' class='k_tabs_more_btn _more_btn_r_ k_box_size'><i style='line-height:" + h + "px' class='fa fa-angle-double-right enabled'></i></span>");
                    let pSize = this.opts.moreBtnSize + "px";
                    $B.DomUtils.css(this.tabHeader, { "padding-left": pSize, "padding-right": pSize });
                    $B.DomUtils.append(this.tabHeader, $l);
                    $B.DomUtils.append(this.tabHeader, $r);
                    $B.DomUtils.css($l, this.opts.moreBtnCss);
                    $B.DomUtils.css($l, { "border-right": "none" });
                    $B.DomUtils.css($r, this.opts.moreBtnCss);
                    this.morePaddLeft = this.opts.moreBtnSize;
                    this.$lbtn = $l;
                    this.$rbtn = $r;
                    this._bindMoreBtnEvent();
                    if (this.$actLine) {
                        let actLeft = $B.DomUtils.position(this.$actLine).left + this.opts.moreBtnSize;
                        $B.DomUtils.css(this.$actLine, { left: actLeft });
                    }
                }
            } else {
                if (this.$lbtn) {
                    $B.DomUtils.css($warp, { width: "100%" });
                    $B.DomUtils.css(this.tabHeader, { "padding-left": "0px", "padding-right": "0px" });
                    this.morePaddLeft = 0;
                    $B.DomUtils.remove(this.$lbtn);
                    $B.DomUtils.remove(this.$rbtn);
                    this.$lbtn = undefined;
                    this.$rbtn = undefined;
                    if (this.$actLine) {
                        let actLeft = $B.DomUtils.position(this.$actLine).left - this.opts.moreBtnSize;
                        $B.DomUtils.css(this.$actLine, { left: actLeft });
                    }
                }
                if ($warp.style.left !== "0px") {
                    if ($warp.style.left !== "") {
                        let shift = Math.abs(parseFloat($warp.style.left.replace("px", "")));
                        let left = $B.DomUtils.css(this.$actLine, "left") + shift;
                        this.$actLine.style.left = left + "px";
                    }
                    $warp.style.left = "0px";
                }
            }
        } else {//垂直位置

        }
    }
    _clearSytleProp(el, propName) {
        let styleObj = $B.style2cssObj(el);
        delete styleObj[propName];
        let styleAtrr = $B.cssObj2string(styleObj);
        $B.DomUtils.attribute(el, { "style": styleAtrr });
    }
    openTabEv($it){       
        let idx = parseInt($B.DomUtils.attribute($it, "index"));
        let opt = this.opts.tabs[idx];
        if(opt.url){
            window.open(opt.url, opt.text);
        }else{
            $B.alert($B.config.urlError);
        }
    }
    onClickEv($it, completeFN) {
        var activedCls = "k_tab_" + this.opts.position + "_" + this.opts.style + "_act";
        if (this.$activeted) {
            $B.DomUtils.removeClass(this.$activeted, activedCls);
            if (this.opts.actItemBackColor) {
                this._clearSytleProp(this.$activeted, "background-color");
            }
            if (this.opts.actItemFontColor) {
                let childs = Array.from(this.$activeted.children);
                for (let i = 0; i < childs.length; i++) {
                    this._clearSytleProp(childs[i], "color");
                }
            }
        }
        this.$activeted = $it;
        $B.DomUtils.addClass(this.$activeted, activedCls);
        if (this.opts.actItemBackColor) {
            $B.DomUtils.css(this.$activeted, { "background-color": this.opts.actItemBackColor });
        }
        if (this.opts.actItemFontColor) {
            let childs = Array.from(this.$activeted.children);
            for (let i = 0; i < childs.length; i++) {
                let el = childs[i];
                let styleObj = $B.style2cssObj(el);
                styleObj["color"] = this.opts.actItemFontColor + " !important";
                let styleAtrr = $B.cssObj2string(styleObj);
                $B.DomUtils.attribute(el, { "style": styleAtrr });
            }
        }
        if (this.$actLine) {
            if (this.$actLine.style.display === "none") {
                this.$actLine.style.display = "inline-block";
            }
            let comFN = undefined;
            if (typeof completeFN === "function") {
                comFN = completeFN;
            }
            this._updateHActLinePos(comFN);
        }
        let idx = parseInt($B.DomUtils.attribute(this.$activeted, "index"));
        let opt = this.opts.tabs[idx];
        let childs = Array.from(this.tabBody.children);
        let actBody = childs[idx];
        if (!actBody) {
            console.log("索引错误！");
            return;
        }  
        let onShow = () => {
            let byEl = actBody;
            if ($B.DomUtils.hasClass(byEl, "k_tab_diyscroll")) {
                byEl = actBody.firstChild.firstChild;
            }
            if (opt.url) {
                if (this.opts.reload || !byEl.firstChild || (typeof completeFN !== "function" && completeFN)) {
                    this._load(byEl, opt);
                }
            }
        };
        if (this.$actbody === actBody) {
            onShow();
        } else {
            if (this.$actbody) {   
                if(this.opts.animate){
                    let $prtEl = this.$actbody.parentNode;
                    let prevEl = actBody.previousSibling;
                    let isPrev = false;
                    while(prevEl){
                        if(this.$actbody === prevEl){
                            isPrev = true;
                            break;
                        }
                        prevEl = prevEl.previousSibling;
                    }                  
                    $prtEl.style.overflow = "hidden"; 
                    let height =  $B.Dom.outerHeight(this.$actbody);
                    onShow();
                    if(isPrev){
                        height = -height;   
                        actBody.style.display = "";                    
                    }
                    $B.animate(this.$actbody,{top:height},{
                        duration:300, 
                        progress:()=>{
                           let top = this.$actbody.style.top; 
                           if(isPrev){
                                actBody.style.top = top; 
                           }else{
                                top = parseFloat(top.replace("px","")) - height;                                
                                actBody.style.top = top +"px"; 
                                actBody.style.display = "";
                           }                                                   
                        },
                        complete:()=>{
                            this.$actbody.style.display = "none";  
                            this.$actbody.style.top = "0px";  
                            actBody.style.top = "0px"; 
                            this.$actbody = actBody;  
                            $prtEl.style.overflow = "auto";                                        
                        }
                    });                                    
                }else{
                    this.$actbody.style.display = "none";
                    actBody.style.display = "";
                    onShow();
                    this.$actbody = actBody;
                }
            } else {
                actBody.style.display = "";
                onShow();
                this.$actbody = actBody;
            }          
        }
    }
    _updateHActLinePos(completeFN) {
        let isHoriUI = this.opts.position === "top" || this.opts.position === "bottom";
        let size;
        if (isHoriUI) {
            let w = $B.DomUtils.outerWidth(this.$activeted);
            if (this.opts.style === "normal") {
                w = w - 1;
            }
            size = w + "px";
        } else {
            let w = $B.DomUtils.outerHeight(this.$activeted);
            if (this.opts.style === "normal") {
                w = w - 1;
            }
            size = w + "px";
        }
        let preEl = this.$activeted.previousSibling;
        let shiftLeft = $B.DomUtils.position(this.tabHeader.firstChild).left;
        let pos = shiftLeft - this.morePaddLeft;
        while (preEl) {
            if (isHoriUI) {
                pos = pos + $B.DomUtils.outerWidth(preEl);
            } else {
                pos = pos + $B.DomUtils.outerHeight(preEl);
            }
            preEl = preEl.previousSibling;
        }
        let lineCss;
        if (isHoriUI) {
            pos = this.morePaddLeft + pos;
            lineCss = { width: size, left: pos + "px" };
        } else {
            $B.DomUtils.attribute(this.$actLine, { "top": pos });
            let srcolltop = $B.DomUtils.scrollTop(this.tabHeader.firstChild.firstChild);
            pos = pos - srcolltop;
            lineCss = { height: size, top: pos + "px" };
        }
        let aniOpt = { duration: 360 };
        if (completeFN) {
            aniOpt.complete = completeFN;
        }
        $B.animate(this.$actLine, lineCss, aniOpt);
    }
    _load(el, opt) {
        //console.log("onShow url " + opt.url);
        let url = opt.url;
        var dataType = opt.dataType ? opt.dataType : "html";
        var isFun = typeof this.opts.onLoaded === 'function';
        if (url.indexOf("?") > 0) {
            url = url + "&_t_=" + $B.generateMixed(5);
        } else {
            url = url + "?_t_=" + $B.generateMixed(5);
        }
        let wrap = el;
        let isNewIfr = false;
        var loading = $B.getLoadingEl();
        if (dataType === "iframe") {
            if (!this.ifrIdex) {
                this.ifrIdex = 1;
            } else {
                this.ifrIdex++;
            }
            let ifrEL = $B.DomUtils.children(wrap, "iframe");
            if (ifrEL.length === 0) {
                ifrEL = $B.getIframeEl("k_tabs_content_ifr");
                $B.DomUtils.css(el, { height: "100%", "overflow": "auto" });
                let ifrId = this.id + "_ifr_" + this.ifrIdex;
                $B.DomUtils.attribute(ifrEL, { "name": ifrId, "id": ifrId });
                $B.DomUtils.append(wrap, ifrEL);
                isNewIfr = true;
                wrap = ifrEL;
                if (!this.opts.ifrScroll) {
                    $B.DomUtils.attribute(ifrEL, { "scrolling": "no" });
                    $B.DomUtils.bind(ifrEL, {
                        mouseenter: () => {
                            $B.DomUtils.attribute(ifrEL, { "scrolling": "auto" });
                        },
                        mouseleave: () => {
                            $B.DomUtils.attribute(ifrEL, { "scrolling": "no" });
                        }
                    });
                }else{
                    $B.DomUtils.attribute(ifrEL, { "scrolling": this.opts.ifrScroll });
                }
            } else {
                wrap = ifrEL[0];
                wrap.contentDocument.body.innerHTML = "<p></p>";
            }
        }
        $B.DomUtils.prepend(el, loading);
        var _this = this;
        setTimeout(() => {
            if (dataType === "html") {
                $B.htmlLoad({
                    url: url,
                    success: function (res) {
                        wrap.innerHTML = res;
                        setTimeout(()=>{
                            if (isFun) {
                                _this.opts.onLoaded.call(wrap, opt, {});
                            }
                        },1);                        
                        $B.bindInputClear(wrap);
                    },
                    complete: function () {
                        $B.removeLoading(loading, () => {
                            loading = undefined;
                        });
                    }
                }, wrap);
            } else if (dataType === "json") {
                let method = (url.indexOf(".data") > 0 || url.indexOf(".json") > 0) ? "GET" : "POST";
                $B.request({
                    dataType: 'json',
                    url: url,
                    type: method,
                    onErrorEval: true,
                    ok: function (message, data) {
                        if (isFun) {
                            _this.opts.onLoaded.call(wrap, opt, data);
                        }
                    },
                    final: function (res) {
                        try {
                            $B.removeLoading(loading, () => {
                                loading = undefined;
                            });
                        } catch (ex) {
                        }
                    },
                    fail: function (arg1, arg2, arg3) {
                    }
                });
            } else {
                if (isNewIfr) {
                    $B.DomUtils.onload(wrap, () => {
                        var url = $B.DomUtils.attribute(wrap, "src");
                        if (url !== "") {                           
                            try {
                                loading = wrap.previousSibling;
                                $B.removeLoading(loading, () => {
                                    loading = undefined;
                                });
                            } catch (ex) {
                            }
                            let ifrBody = wrap.contentDocument.body;
                            if (isFun) {
                                _this.opts.onLoaded.call(ifrBody, opt, wrap);
                            }
                            // var ua = window.navigator.userAgent;
                            // var isFirefox = ua.indexOf("Firefox") !== -1;
                            // try {
                            //     var ifrBody = this.contentDocument.body;
                            //     $B.DomUtils.append(ifrBody, "<span id='_window_ifr_id_' style='display:none'>" + ifrId + "</span>");
                            //     if (isFirefox) {
                            //         // ifrBody.find("a").each(function () {
                            //         //     var $a = $(this);
                            //         //     if ($a.attr("href").toLowerCase().indexOf("javascript") > -1) {
                            //         //         $a.attr("href", "#");
                            //         //     }
                            //         // });
                            //     }
                            // } catch (ex) { }
                        }
                    });
                }
                wrap.src = url;
            }
        }, 1);
    }
    destroy(isForce) {
        if (this.$ctxmenu) {
            $B.DomUtils.offEvents(this.$ctxmenu);
            $B.DomUtils.remove(this.$ctxmenu);
        }
        super.destroy(isForce);
    }
}
$B["Tabs"] = Tabs;